<html>
<head><meta charset="utf-8"><title>Deprecating `*Box` special behavior. · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html">Deprecating `*Box` special behavior.</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="221277990"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221277990" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221277990">(Dec 31 2020 at 08:56)</a>:</h4>
<p>There's something special on the <code>Box</code> type in the standard library: </p>
<p>for a variable <code>boxed</code> with type <code>Box&lt;T&gt;</code>,<br>
with <code>let val = *boxed;</code> this will always compile, but what it does depends on whether <code>T</code> is a non-<code>Copy</code> type.</p>
<p>If it is a <code>Copy</code> type, this uses <code>Deref</code> to create a &amp;T and copies the value.</p>
<p><strong>If it is not, this triggers something special: it moves the value out and de-allocates the box allocation. This behavior is currently stable and not seen on other types.</strong></p>
<p>I feel this behavior is rather ad-hoc, hard to use correctly, hard-to-find for beginners and doesn't scale well to other types. Maybe it is a good idea to eventually deprecate this behavior? I'm curious what others think of this. Thanks!</p>



<a name="221278059"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278059" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278059">(Dec 31 2020 at 08:58)</a>:</h4>
<p>Removing this would make it impossible to call <code>Box&lt;dyn FnOnce()&gt;</code> as that relies on moving the closure out of the box.</p>



<a name="221278068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278068">(Dec 31 2020 at 08:59)</a>:</h4>
<p>In addition I have used this behavior on multiple occasions to move out of a <code>Box&lt;dyn Any&gt;</code> after downcasting.</p>



<a name="221278072"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278072" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278072">(Dec 31 2020 at 08:59)</a>:</h4>
<p>That's using unsized rvalues unstable feature, right?</p>



<a name="221278146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278146">(Dec 31 2020 at 09:01)</a>:</h4>
<p><code>impl FnOnce() for Box&lt;dyn FnOnce()&gt;</code> internally uses the unsized rvalue feature, but the impl is usable on stable.</p>



<a name="221278201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278201">(Dec 31 2020 at 09:02)</a>:</h4>
<p>yes, i feel it could use some special handling, since it's an implementation detail.</p>



<a name="221278227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278227">(Dec 31 2020 at 09:03)</a>:</h4>
<p>So you want to remove special handling in one very useful case and add special handling in another much less general case?</p>



<a name="221278334"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278334" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278334">(Dec 31 2020 at 09:05)</a>:</h4>
<p>Not really, i just want to deprecate directly using it from the users.</p>



<a name="221278388"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278388" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278388">(Dec 31 2020 at 09:06)</a>:</h4>
<p>I also want to add a <code>Box::into_inner</code> function for general (sized) use.</p>



<a name="221278586"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278586" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278586">(Dec 31 2020 at 09:11)</a>:</h4>
<p>the <a href="https://github.com/rust-lang/rust/pull/80438">implementation</a> is here, i'm not totally sure how to make this function support unsized rvalues <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span></p>



<a name="221278625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278625">(Dec 31 2020 at 09:12)</a>:</h4>
<p>What about starting with the latter? Adding <code>Box::into_inner()</code>, for discoverability, with something saying that <code>Box</code> is special and that <code>into_inner</code> is idiomatically replaced with <code>*</code></p>



<a name="221278888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221278888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221278888">(Dec 31 2020 at 09:19)</a>:</h4>
<p>yes, i like the idea of starting with the function.</p>



<a name="221285430"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285430" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285430">(Dec 31 2020 at 11:52)</a>:</h4>
<blockquote>
<p>If it is not, this triggers something special: it moves the value out and de-allocates the box allocation. This behavior is currently stable and not seen on other types.</p>
</blockquote>
<p>It doesn't deallocate immediately, deallocation still happens when the original <code>Box</code> goes out of scope. That lets you do things like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">apply</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// replace contents in-place</span>
<span class="w">  </span><span class="n">b</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="221285445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285445">(Dec 31 2020 at 11:52)</a>:</h4>
<p>it's not really ad-hoc; this behavior is a reflection of the fact that the borrow and move checkers "understand" <code>Box</code> and basically treat <code>Box&lt;T&gt;</code> and <code>T</code> the same. That is quite useful indeed.</p>



<a name="221285461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285461">(Dec 31 2020 at 11:53)</a>:</h4>
<p>IMO the fix is not to strip <code>Box</code> of this useful functionality, but to make this functionality available to other types as well. This is the (in)famous <code>DerefMove</code> that has been talked about for years.</p>



<a name="221285736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285736">(Dec 31 2020 at 11:58)</a>:</h4>
<blockquote>
<p>It doesn't deallocate immediately, deallocation still happens when the original <code>Box</code> goes out of scope. That lets you do things like</p>
</blockquote>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">apply</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// replace contents in-place</span>
<span class="w">  </span><span class="n">b</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Oh. I did not know that. That seems really annoying to implement sans magic.</p>



<a name="221285839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285839">(Dec 31 2020 at 12:01)</a>:</h4>
<p>It's the same "magic" as a local variable:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="nc">SomeNonCopyType</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">..</span><span class="p">.;</span><span class="w"></span>
<span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w"> </span><span class="c1">// replace contents in-place</span>
</code></pre></div>



<a name="221285958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221285958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221285958">(Dec 31 2020 at 12:03)</a>:</h4>
<p>However, that doesn't go through a trait method. A non-magic impl of that behaviour would have to (and in the lccc impl <a href="https://github.com/LightningCreations/lccc/blob/50c08a4619c021ea51e53c8c7c412981a1dcd217/rust/liballoc/src/boxed.rs#L35">does</a>)</p>



<a name="221286013"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221286013" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221286013">(Dec 31 2020 at 12:04)</a>:</h4>
<p>I don't think there's a way this can be done for A=Global portably.</p>



<a name="221286184"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221286184" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221286184">(Dec 31 2020 at 12:09)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E/near/221286013">said</a>:</p>
<blockquote>
<p>I don't think there's a way this can be done for A=Global portably.</p>
</blockquote>
<p>not sure what you mean; I think this should work regardless of the allocator?</p>



<a name="221286228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221286228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221286228">(Dec 31 2020 at 12:10)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E/near/221285958">said</a>:</p>
<blockquote>
<p>However, that doesn't go through a trait method. A non-magic impl of that behaviour would have to (and in the lccc impl <a href="https://github.com/LightningCreations/lccc/blob/50c08a4619c021ea51e53c8c7c412981a1dcd217/rust/liballoc/src/boxed.rs#L35">does</a>)</p>
</blockquote>
<p>none of these examples go through a trait method. <code>*b</code> where <code>b: Box</code> is not a trait method call, it is a primitive <code>Deref</code> place projection (similar to <code>*</code> on <code>&amp;</code>/<code>&amp;mut</code>).</p>



<a name="221286520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221286520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221286520">(Dec 31 2020 at 12:18)</a>:</h4>
<p>In my case, the goal is to implement Box w/o magic (if you don't count the spam of <code>#[__lccc::*]</code> attributes as "magic"). This necessarily would use a trait method call to implement the moving behaviour. The problem is: how do I track boxes that have been moved out of without altering the layout of <code>Box&lt;T,Global&gt;</code>.</p>



<a name="221286612"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221286612" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221286612">(Dec 31 2020 at 12:20)</a>:</h4>
<p>Though if the behaviour was generalized in rust itself, it would run into the same issue (though it's easier to solve in other cases, you can simply use a small field for tracking the drop state)</p>



<a name="221287018"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221287018" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221287018">(Dec 31 2020 at 12:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E/near/221286520">said</a>:</p>
<blockquote>
<p>In my case, the goal is to implement Box w/o magic (if you don't count the spam of <code>#[__lccc::*]</code> attributes as "magic"). This necessarily would use a trait method call to implement the moving behaviour. The problem is: how do I track boxes that have been moved out of without altering the layout of <code>Box&lt;T,Global&gt;</code>.</p>
</blockquote>
<p>Rustc just keeps the <code>Box&lt;T, Global&gt;</code> but in the drop elaboration mir pass, the <code>Drop</code> terminator is replaced with a call to <code>box_free</code>. You have the same problem for regular variables which you can move out of too. In which case you have to remove the <code>Drop</code> terminator. Only in this case you also have to add a <code>box_free</code> call. The drop elaboration pass is necessary in any case as it handles the case where a variable is only sometimes initialized. For example only when an if is not taken.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="nb">String</span>::<span class="n">new</span><span class="p">());</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_0</span>: <span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_1</span>: <span class="nc">std</span>::<span class="n">boxed</span>::<span class="nb">Box</span><span class="o">&lt;</span><span class="n">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_2</span>: <span class="nc">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">scope</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">debug</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb0</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_2</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">_2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">String</span>::<span class="n">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">bb1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb1</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span>::<span class="n">new</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="n">_2</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">bb2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb2</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_2</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">_0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="nb">drop</span><span class="p">(</span><span class="n">_1</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">bb3</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb3</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>vs</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="nb">String</span>::<span class="n">new</span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="o">*</span><span class="n">a</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_0</span>: <span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_1</span>: <span class="nc">std</span>::<span class="n">boxed</span>::<span class="nb">Box</span><span class="o">&lt;</span><span class="n">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_2</span>: <span class="nc">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_3</span>: <span class="nc">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_4</span>: <span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_5</span>: <span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">scope</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">debug</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">_1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb0</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_2</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">_2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">String</span>::<span class="n">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">bb2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb1</span><span class="w"> </span><span class="p">(</span><span class="n">cleanup</span><span class="p">)</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">resume</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb2</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">_1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span>::<span class="n">new</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="n">_2</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">bb3</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb3</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_2</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageLive</span><span class="p">(</span><span class="n">_3</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">_3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">_1</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="nb">drop</span><span class="p">(</span><span class="n">_3</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="p">[</span><span class="k">return</span>: <span class="nc">bb4</span><span class="p">,</span><span class="w"> </span><span class="n">unwind</span>: <span class="nc">bb6</span><span class="p">];</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb4</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_3</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="n">_0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="n">_5</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">alloc</span>::<span class="n">alloc</span>::<span class="n">box_free</span>::<span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="p">(</span><span class="n">_1</span><span class="p">.</span><span class="mi">0</span>: <span class="nc">std</span>::<span class="n">ptr</span>::<span class="n">Unique</span><span class="o">&lt;</span><span class="n">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="o">&gt;</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="nc">bb5</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb5</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">StorageDead</span><span class="p">(</span><span class="n">_1</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">bb6</span><span class="w"> </span><span class="p">(</span><span class="n">cleanup</span><span class="p">)</span>: <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">_4</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">alloc</span>::<span class="n">alloc</span>::<span class="n">box_free</span>::<span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="p">(</span><span class="n">_1</span><span class="p">.</span><span class="mi">0</span>: <span class="nc">std</span>::<span class="n">ptr</span>::<span class="n">Unique</span><span class="o">&lt;</span><span class="n">std</span>::<span class="n">string</span>::<span class="nb">String</span><span class="o">&gt;</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="nc">bb1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="221287946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221287946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221287946">(Dec 31 2020 at 12:48)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> well, <code>Box</code> fundamentally <em>is</em> magic in Rust since it is the only type with <code>DerefMove</code> behavior. This is not a new insight, though maybe not a widely-known one either.</p>



<a name="221287952"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221287952" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221287952">(Dec 31 2020 at 12:48)</a>:</h4>
<p>I don't see a way for other Rust implementations to avoid this, if they want to remain compatible.</p>



<a name="221287976"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221287976" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221287976">(Dec 31 2020 at 12:49)</a>:</h4>
<p>and as I said above, IMO the fix is to have <code>DerefMove</code> for real -- then <code>Box</code> isn't special any more for being the only type that "implements" this</p>



<a name="221288085"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288085" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288085">(Dec 31 2020 at 12:51)</a>:</h4>
<p>Indeed. My point was, given the above behaviour, <code>Box</code> would remain magic with <code>DerefMove</code> (as shown, lccc has an (unstable) <code>DerefMove</code> trait which handles the moving deref).</p>



<a name="221288165"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288165" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288165">(Dec 31 2020 at 12:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E/near/221288085">said</a>:</p>
<blockquote>
<p>Indeed. My point was, given the above behaviour, <code>Box</code> would remain magic with <code>DerefMove</code> (as shown, lccc has an (unstable) <code>DerefMove</code> trait which handles the moving deref).</p>
</blockquote>
<p>Doesn't this just mean that the "real" <code>DerefMove</code> is more complicated than what your unstable trait provides?</p>



<a name="221288190"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288190" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288190">(Dec 31 2020 at 12:53)</a>:</h4>
<p><code>DerefMove</code> has to be able to model the idea of moving out of something and leaving behind a "skeleton" (something similar to <code>Box&lt;MaybeUninit&lt;T&gt;&gt;</code>) that can be "reinitialized"</p>



<a name="221288258"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288258" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288258">(Dec 31 2020 at 12:54)</a>:</h4>
<p>doesn't <code>Box</code> also support partial moves , like moving out only the first field of a <code>Box&lt;(Vec&lt;T&gt;, Vec&lt;T&gt;)&gt;</code>?</p>



<a name="221288424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288424">(Dec 31 2020 at 12:57)</a>:</h4>
<p>Well, the primary thing would be<br>
1) The proposal for DerefMove is (self)-&gt;Self::Target, IIRC.<br>
2) There isn't a way, on Box, to store drop glue information, since the layout of <code>Box&lt;T,Global&gt;</code> is fixed (unless it's possible to store a "control block" in the allocation)<br>
3) The above shown by <span class="user-mention" data-user-id="133247">@bjorn3</span> still requires special information about Box, since it would not be generally applicable to all DerefMove types (in particular, that would not work for <code>Box&lt;T,System&gt;</code>.</p>



<a name="221288647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288647">(Dec 31 2020 at 13:00)</a>:</h4>
<blockquote>
<p>(in particular, that would not work for Box&lt;T,System&gt;.</p>
</blockquote>
<p>you mean because it calls <code>box_free</code>?</p>



<a name="221288675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288675">(Dec 31 2020 at 13:01)</a>:</h4>
<p>but if <code>DerefMove</code> is <code>(self) -&gt; (Self::Target, Self::Skeleton)</code> then dropping the skeleton could do the right thing without storing "drop glue information"</p>



<a name="221288693"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288693" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288693">(Dec 31 2020 at 13:01)</a>:</h4>
<p>IOW, the information could be stored in the type</p>



<a name="221288714"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288714" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288714">(Dec 31 2020 at 13:01)</a>:</h4>
<p>modelling partial moves would likely require GATs/ATCs though</p>



<a name="221288842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288842">(Dec 31 2020 at 13:03)</a>:</h4>
<p>not sure what <code>ATC</code>s are, but <code>&amp;owned</code> references could also solve partial moves. <code>Skeleton</code> could in that case also have a lifetime on it that ensures it is not dropped while the <code>&amp;owned</code> in <code>Self::Target</code> is still accessible.</p>



<a name="221288893"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288893" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288893">(Dec 31 2020 at 13:04)</a>:</h4>
<p>ah no, that won' t work, ignore me. The problem is multiple calls to <code>deref_move</code></p>



<a name="221288984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221288984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221288984">(Dec 31 2020 at 13:06)</a>:</h4>
<p>If we make <code>DerefMove</code> a lang item, we could proabably make it work by having a MIR transform that rewrites the MIR to have the drop and similar at the appropriate sites</p>



<a name="221289001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221289001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221289001">(Dec 31 2020 at 13:07)</a>:</h4>
<p>ATC = Associated Type Constructor / GAT = Generic Associated Types</p>



<a name="221289622"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221289622" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221289622">(Dec 31 2020 at 13:18)</a>:</h4>
<p>Given that we already have <code>Box::init</code>, what about:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">take</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="nb">Box</span><span class="o">&lt;</span><span class="n">MaybeUninit</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>?<br>
Obviously partial moves are very hard to express within a trait unless we go into frunk-level of generic clauses + a combinatorial explosion of same-repr siblings of the original struct but where each possible subset of fields is replaced with <code>MaybeUninit</code> equivalents. I think a simple <code>map_inner</code> with leak-on-unwind behavior could be quite good at handling most use cases with a very simple API</p>



<a name="221289837"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221289837" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221289837">(Dec 31 2020 at 13:23)</a>:</h4>
<blockquote>
<p>unless we go into frunk-level of generic clauses + a combinatorial explosion of same-repr siblings of the original struct </p>
</blockquote>
<p>or we use associated type cosntructors and compiler magic, turning <code>Constructor&lt;(T, U)&gt;</code> into <code>Constructor&lt;(MaybeUninit&lt;T&gt;, U)&gt;</code></p>



<a name="221289853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221289853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221289853">(Dec 31 2020 at 13:23)</a>:</h4>
<blockquote>
<p>Given that we already have Box::init, what about:</p>
</blockquote>
<p>you mean <code>Box::new_uninit</code>?</p>



<a name="221300401"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221300401" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221300401">(Dec 31 2020 at 16:28)</a>:</h4>
<p>What about</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">DerefMove</span>: <span class="nc">DerefMut</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">move_out</span><span class="p">(</span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="bp">Self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span>::<span class="n">Target</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">drop_skeleton</span><span class="p">(</span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="bp">Self</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>where <code>DerefMove::drop_skeleton</code> is used instead of <code>drop_in_place</code> when the value is moved out.</p>



<a name="221310436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221310436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221310436">(Dec 31 2020 at 19:16)</a>:</h4>
<p>@RalfJ Ummm, i see what you mean. And i agree it's state of art. But isn't this a little too complicated for ordinary users...<br>
Your example:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">apply</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// replace contents in-place</span>
<span class="w">  </span><span class="n">b</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Is just language-level shorthand for:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">apply</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Box</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">take_mut</span>::<span class="n">take</span><span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">as_mut</span><span class="p">(),</span><span class="w"> </span><span class="n">f</span><span class="p">);</span><span class="w"> </span><span class="c1">// replace contents in-place</span>
<span class="w">  </span><span class="n">b</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>which also applies to other types well. I feel the <code>DerefMove</code> trait doesn't really pay off since it would be so rarely used...</p>



<a name="221310489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221310489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221310489">(Dec 31 2020 at 19:17)</a>:</h4>
<p><code>take_mut::take</code> has to abort on panic to prevent unsafety, while <code>*b = f(*b)</code> simply deallocates the memory backing the <code>Box</code> and then continues unwinding.</p>



<a name="221310567"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221310567" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221310567">(Dec 31 2020 at 19:18)</a>:</h4>
<p>yes, indeed.</p>



<a name="221354052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Deprecating%20%60%2ABox%60%20special%20behavior./near/221354052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Deprecating.20.60*Box.60.20special.20behavior.2E.html#221354052">(Jan 01 2021 at 14:33)</a>:</h4>
<p>yeah, this is way simpler than <code>take_mut</code> because things are fully owned, not borrowed</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>